package org.opens.util;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.UUID;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * 功能描述
 *
 * @author: zhangyuming
 * @date: 2024/3/28 15:55
 */
@Slf4j
public class FtpUtil {

    /**
     * 上传本地文件到ftp服务器
     * @param ip    ip
     * @param port  端口
     * @param username  用户名
     * @param password  密码
     * @param localFilePath 本地路径
     * @param remoteDirectory   远程目录
     */
    public static void upload(String ip, int port, String username, String password, String localFilePath, String remoteDirectory) {
        Assert.notBlank(ip);
        Assert.notNull(port);
        Assert.notBlank(username);
        Assert.notBlank(password);
        Assert.notBlank(localFilePath);
        Assert.notBlank(remoteDirectory);

        // 如果远程目录以/结尾，则去掉
        if (remoteDirectory.endsWith("/")) {
            remoteDirectory = remoteDirectory.substring(0, remoteDirectory.length() - 1);
        }

        FTPClient ftpClient = new FTPClient();
        FileInputStream inputStream = null;

        try {
            File localFile = new File(localFilePath);
            // 检测源文件是否存在
            if (!localFile.exists()) {
                throw new IllegalArgumentException("文件[" + localFilePath + "]不存在！");
            }
            inputStream = new FileInputStream(localFile);

            ftpClient.connect(ip, port);
            ftpClient.login(username, password);
            ftpClient.enterLocalPassiveMode();
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

            // 设置字符编码为UTF-8
            ftpClient.setControlEncoding("UTF-8");

            // 如果目录不存在，则创建目录
            // ftp不能直接创建多级目录
            String[] directories = remoteDirectory.split("/");
            for (String directory : directories) {
                if (!directory.isEmpty()) {
                    // ftp相关的api没有对应的exists方法，如果changeWorkingDirectory不存在的目录，会返回false
                    if (!ftpClient.changeWorkingDirectory(directory)) {
                        boolean created = ftpClient.makeDirectory(directory);
                        if (created) {
                            log.info("自动创建ftp目录成功: {}", directory);
                        } else {
                            throw new RuntimeException("自动创建ftp目录失败: " + directory);
                        }
                        // 切换到新创建的目录
                        ftpClient.changeWorkingDirectory(directory);
                    }
                }
            }

            String remoteFileName = new String(localFile.getName().getBytes("UTF-8"), "ISO-8859-1");
            String remoteFilePath = remoteDirectory + "/" + remoteFileName;

            // 进行上传
            ftpClient.storeFile(remoteFilePath, inputStream);

            log.info("文件[ {} ]上传至ftp成功[ {} ]", localFilePath, remoteDirectory + "/" + localFile.getName());
        } catch (IOException ex) {
            log.error("上传ftp文件发生异常", ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException ex) {
                log.error("关闭本地文件流发生异常", ex);
            }
            try {
                if (ftpClient.isConnected()) {
                    ftpClient.logout();
                    ftpClient.disconnect();
                }
            } catch (IOException ex) {
                log.error("关闭ftp连接发生异常", ex);
            }
        }
    }

    public static void main(String[] args) {
        String dir = "/logs/" + UUID.fastUUID();
        //String dir = "/logs/935268a9-bd85-443d-98ae-e0afdb1e38fb";
        System.out.println(dir);
        upload("192.168.1.31", 21, "root", "root", "C:\\Users\\99126\\Desktop\\ddd1\\qqqqqqqq\\张三.xls", dir);
    }

}
